#include "stdlib.hpp"
#include <cstdarg>

namespace purewell
{

PWLibLog& gLibLog(PWLibLog::getInstance());

PWLibLog&
PWLibLog::getInstance(void)
{
	static PWLibLog inst;
	return inst;
}

PWLibLog::PWLibLog() : m_os(&std::cerr)
{
}

PWLibLog::~PWLibLog()
{
}

std::ostream*
PWLibLog::setStream(std::ostream* os)
{
	std::ostream* ret(m_os);
	m_os = os;
	return ret;
}

std::ostream*
PWLibLog::getStream(void)
{
	return m_os;
}

void
PWLibLog::trace(const char* file, int line, const char* func,
	const char* fmt, ...)
{
	if ( !m_os )
	{
		return;
	}

	char buf[1024*10];
	va_list lst;
	va_start(lst, fmt);
#if defined(HAVE_VSNPRINTF)
	vsnprintf(buf, sizeof(buf), fmt, lst);
#else
	vsprintf(buf, fmt, lst);
#endif//HAVE_VSNPRINTF
	va_end(lst);
	buf[sizeof(buf)-1] = 0x00;

	char nowstr[64];
#ifndef WIN32
	struct tm res;
	time_t now(time(NULL));
	localtime_r(&now, &res);
	sprintf(nowstr, "%04d/%02d/%02d %02d:%02d:%02d ",
		res.tm_year+1900, res.tm_mon+1, res.tm_mday,
		res.tm_hour, res.tm_min, res.tm_sec);
#else
	SYSTEMTIME tm;
	GetLocalTime(&tm);
	sprintf(nowstr, "%04d/%02d/%02d %02d:%02d:%02d ",
		tm.wYear, tm.wMonth, tm.wDay,
		tm.wHour, tm.wMinute, tm.wSecond);
#endif//WIN32

#if 0
	(*m_os) << nowstr << basename(file) << ':' << line << ':' << func
		<< ' ' << buf << std::endl;
#else
	(*m_os) << nowstr << file << ':' << line << ':' << func
		<< ' ' << buf << std::endl;
#endif

	m_os->flush();
}

void
PWLibLog::format(const char* fmt, ...)
{
	if ( !m_os )
	{
		return;
	}

	char buf[1024*10];
	va_list lst;
	va_start(lst, fmt);
#if defined(HAVE_VSNPRINTF)
	vsnprintf(buf, sizeof(buf), fmt, lst);
#else
	vsprintf(buf, fmt, lst);
#endif//HAVE_VSNPRINTF
	va_end(lst);
	buf[sizeof(buf)-1] = 0x00;

	char nowstr[64];
#ifndef WIN32
	struct tm res;
	time_t now(time(NULL));
	localtime_r(&now, &res);
	sprintf(nowstr, "%04d/%02d/%02d %02d:%02d:%02d ",
		res.tm_year+1900, res.tm_mon+1, res.tm_mday,
		res.tm_hour, res.tm_min, res.tm_sec);
#else
	SYSTEMTIME tm;
	GetLocalTime(&tm);
	sprintf(nowstr, "%04d/%02d/%02d %02d:%02d:%02d ",
		tm.wYear, tm.wMonth, tm.wDay,
		tm.wHour, tm.wMinute, tm.wSecond);
#endif//WIN32

	(*m_os) << nowstr << buf << std::endl;
	m_os->flush();
}

};//namespace purewell

